package com.jike.jkgame.data;

import android.os.Handler;
import android.os.Message;
import android.util.Log;

import com.jike.jkgame.Global;

public class Status {

	public int maxValue;
	public String name;
	public int value;
	public long recoverTime;
	public int recoverValue;
	public long timeUntillRecover;
	
	private Handler mTargetHandler;
	private Handler mOldHandler;
	
	public Status(String name, int maxValue, long recovertTime,
			int reconverValue) {
		this.name = name;
		this.value = this.maxValue = maxValue;
		this.recoverTime = recovertTime;
		this.recoverValue = reconverValue;
	}
	
	public Status(String name) {
		this.name = name;
		this.recoverTime = 5 * 60 * 1000;
		this.recoverValue = 1;
	}
	
	public void setTargetHandler(Handler handler) {
		mTargetHandler = handler;
		
	}

	public boolean use(int used) {
		if (used < 0 || used > value) {
			return false;
		}

		value -= used;
		return true;
	}

	public void passTime(long millis) {
		if (millis >= getTotalMillisUntillFull()) {
			setFull();
			return;
		}
		
		add((int) (millis / recoverTime));

		long remain = millis % recoverTime;
		
		if (!isFull()) {
			timeUntillRecover -= remain;
			if (timeUntillRecover <= 0) {
				add(recoverValue);
				if (isFull()) {
					setFull();
				} else {
					timeUntillRecover += recoverTime;
				}
			}
		} else {
			setFull();
		}

	}

	public void onTick(long interval) {
		if (!isFull()) {
			timeUntillRecover -= interval;
			if (timeUntillRecover <= 0) {
				recovery();
				if (isFull()) {
					setFull();
				} else {
					timeUntillRecover += recoverTime;
					
				}
				sendMessage(Global.MessageType.TIME_FINISH);
			} else {
				sendMessage(Global.MessageType.TIME_TICK);
			}

		}
	}

	private void sendMessage(int what) {
		if (mTargetHandler != null) {
			Message msg = mTargetHandler.obtainMessage();
			msg.arg1 = (int) (timeUntillRecover / 1000);
			msg.what = what;
			msg.obj = name;
			mTargetHandler.sendMessage(msg);
		}
	}

	private void recovery() {
		add(recoverValue);

		sendMessage(Global.MessageType.VALUE_UPDATE);
	}

	public void setFull() {
		value = maxValue;
		timeUntillRecover = 0;
		sendMessage(Global.MessageType.TIME_FINISH);
	}

	public boolean add(int added) {
		synchronized (this) {
			if (added < 0) {
				return false;
			}

			value += added;
			if (value > maxValue) {
				value = maxValue;
			}
		}

		return true;
	}

	public boolean isFull() {
		return value >= maxValue;
	}

	public Handler pushTargetHandler(Handler handler) {
		mOldHandler = mTargetHandler;
		mTargetHandler = handler;
		return mOldHandler;
	}
	
	public void restoreTargetHandler() {
		mTargetHandler = mOldHandler;
	}

	public long getTotalMillisUntillFull() {
		if (isFull()) {
			return 0;
		}

		int total = (int) (((maxValue - value) / recoverValue - 1)
				* recoverTime + timeUntillRecover);
		return total;
	}
	
	
}
